package sub

import (
	"bufio"
	"fmt"
	"github.com/urfave/cli/v2"
	"lib/utils"
	"os"
	"os/exec"
	"strings"
)

func UserCommand() *cli.Command {
	var comm = &cli.Command{
		Name:      "user",
		Usage:     "创建用户、挂盘、会话管理、设置目录权限等",
		UsageText: fmt.Sprintf("eg: mccp user -logoffSession=1 "),
		Flags: []cli.Flag{
			&cli.StringFlag{
				Name:  "addRemote",
				Usage: "创建账户，并将账户添加到远程桌面账户组,格式为：-ar=account-pws,账户密码中都不能使用 '-' 符号",
				Action: func(ctx *cli.Context, in string) error {
					ins := strings.Split(in, "-")
					if len(ins) != 2 {
						return cli.Exit(fmt.Sprintf("当前参数：%s,需要接收的参数格式为：account-pws,且密码中不能使用'-'符号", in), 1)
					}
					err := createRemoteWinAccount(ins[0], ins[1])
					if err != nil {
						return cli.Exit(fmt.Sprintf("创建远程桌面账户时发生错误：%s", err.Error()), 1)
					}
					return nil
				},
			},
			&cli.StringFlag{
				Name:  "logoffSession",
				Usage: "注销会话",
				Action: func(ctx *cli.Context, s string) error {
					err := logoffSession(ctx.String("logoffSession"))
					if err != nil {
						return cli.Exit(fmt.Sprintf("获取举手信息时发生错误:[%v]", err), 1)
					}
					w := bufio.NewWriter(os.Stdout)
					_, _ = w.WriteString("")
					_ = w.Flush()
					return nil
				},
			},
			&cli.StringFlag{
				Name:  "crateUserDir",
				Usage: "创建用户独占目录,格式为：-cd=path-account",
				Action: func(ctx *cli.Context, in string) error {
					ins := strings.Split(in, "-")
					if len(ins) != 2 {
						return cli.Exit(fmt.Sprintf("请按格式输入目录路径和账户"), 1)
					}
					err := createMonopolizeDir(ins[0], ins[1])
					if err != nil {
						return cli.Exit(fmt.Sprintf("创建独占目录时发生错误:[%v]", err), 1)
					}
					w := bufio.NewWriter(os.Stdout)
					_, _ = w.WriteString("")
					_ = w.Flush()
					return nil
				},
			},
			&cli.StringFlag{
				Name:  "delMapDir",
				Usage: "删除盘符映射,格式为： -dd=Y ,但是不能删除C盘",
				Action: func(ctx *cli.Context, in string) error {
					if in == "C" {
						return cli.Exit(fmt.Sprintf("该程序不能删除C盘映射"), 1)
					}
					err := unmapDrive(in)
					if err != nil {
						return cli.Exit(fmt.Sprintf("删除盘符映射时发生错误:[%v]", err), 1)
					}
					w := bufio.NewWriter(os.Stdout)
					_, _ = w.WriteString("")
					_ = w.Flush()
					return nil
				},
			},
			&cli.StringFlag{
				Name:  "mappingDir",
				Usage: "映射目录为盘符，格式为：-md=目录路径-盘符名称",
				Action: func(ctx *cli.Context, in string) error {
					ins := strings.Split(in, "-")
					if len(ins) != 2 {
						return cli.Exit(fmt.Sprintf("请按格式输入目录路径和盘符"), 1)
					}
					err := mappingDir(ins[0], ins[1])
					if err != nil {
						return cli.Exit(fmt.Sprintf("将目录映射为盘符时发生错误：%s", err), 1)
					}
					return nil
				},
			},
		},
	}
	comm.Action = func(ctx *cli.Context) error {
		return nil
	}
	return comm
}

// createRemoteWinAccount 创建windows账户并将账户添加到 Remote Desktop Users
func createRemoteWinAccount(account, pws string) (err error) {
	err = createWinAccount(account, pws)
	if err != nil {
		return
	}
	return accountAddGroup(account)
}

// createWinAccount 创建windows账户
func createWinAccount(account, pws string) (err error) {
	// 构建创建用户的命令
	cmd := exec.Command("net", "user", account, pws, "/add")
	// 执行命令并获取输出
	output, err := cmd.CombinedOutput()
	if err != nil {
		err = fmt.Errorf("创建用户时出错: %s，输出: %s", err, string(output))
		return err
	}
	return nil
}

// accountAddGroup 将账户添加到 远程桌面用户组
func accountAddGroup(account string) (err error) {
	// 构建将用户添加到远程桌面用户组的命令
	cmd := exec.Command("net", "localgroup", "Remote Desktop Users", account, "/add")
	// 执行命令并获取输出
	output, err := cmd.CombinedOutput()
	if err != nil {
		err = fmt.Errorf("创建用户时出错: %s，输出: %s", err, string(output))
		return err
	}
	return nil
}

// logoffSession 注销会话
func logoffSession(id string) (err error) {
	cmd := exec.Command("logoff", id)
	// 执行命令并获取输出
	output, err := cmd.CombinedOutput()
	if err != nil {
		err = fmt.Errorf("注销会话时出错: %s，输出: %s", err, string(output))
		return err
	}
	return nil
}

// mappingDir 将目录映射为盘符
func mappingDir(dir string, driveCode string) (err error) {
	// 构建 subst 命令
	cmd := exec.Command("subst", driveCode+":", dir)
	// 执行命令并获取输出
	output, err := cmd.CombinedOutput()
	if err != nil {
		err = fmt.Errorf("映射目录到盘符时出错: %s，输出: %s", err, string(output))
		return err
	}
	return nil
}

// unmapDrive 删除盘符映射
func unmapDrive(driveCode string) (err error) {
	// 构建 subst 命令
	cmd := exec.Command("subst", driveCode+":", "/D")
	// 执行命令并获取输出
	output, err := cmd.CombinedOutput()
	if err != nil {
		err = fmt.Errorf("删除盘符映射时出错: %s，输出: %s", err, string(output))
		return err
	}
	return nil
}

// createMonopolizeDir 创建独占目录
func createMonopolizeDir(dir string, account string) (err error) {
	if !utils.IsExistFolder(dir) {
		err = os.MkdirAll(dir, os.ModePerm)
		if err != nil {
			return
		}
	}
	// 构建 icacls 命令.
	cmd := exec.Command("icacls", dir, "/grant", fmt.Sprintf("%s:(OI)(CI)F", account))
	// 执行命令并获取输出
	output, err := cmd.CombinedOutput()
	if err != nil {
		err = fmt.Errorf("账户: %s授权目录: %s 时出错: %s，输出: %s", account, dir, err, string(output))
		return err
	}
	return nil
}
